using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.XR;

public class HandController : MonoBehaviour
{
    public event Action<Cable, Cable> CableConnected;

    [SerializeField]
    private LayerMask _grabLayer;

    [SerializeField]
    private FixedJoint2D _handL;
    [SerializeField]
    private SpriteSwitch _handVisualL;
    [SerializeField]
    private FixedJoint2D _handR;
    [SerializeField]
    private SpriteSwitch _handVisualR;

    [SerializeField]
    private ParticleSystem _grabEffectL;
    [SerializeField]
    private ParticleSystem _grabEffectR;

    [SerializeField]
    private AudioClip _grabSound;
    [SerializeField]
    private AudioClip _releaseSound;


    // Start is called before the first frame update
    void Start()
    {
        _handL.enabled = false;
        _handR.enabled = false;
    }

    // Update is called once per frame
    void Update()
    {
        if (EventSystem.current.IsPointerOverGameObject()) return;

        if (Input.GetKeyDown(KeyCode.Mouse0))
        {
            Grab(_handL, _grabEffectL, _handVisualL);
        }
        if (Input.GetKeyDown(KeyCode.Mouse1))
        {
            Grab(_handR, _grabEffectR, _handVisualR);
        }
    }

    private void Grab(FixedJoint2D hand,
                      ParticleSystem effect,
                      SpriteSwitch handVisual)
    {
        if (hand.connectedBody != null)
        {
            hand.connectedBody = null;
            hand.enabled = false;
            handVisual.UpdateSprite(false);

            AudioPlayer.Instance.PlaySound(_releaseSound);
            return;
        }

        var results = Physics2D.OverlapCircle(hand.transform.position, 1f, _grabLayer);
        if (results != null)
        {
            if (results.TryGetComponent(out Rigidbody2D body))
            {
                if (body.gameObject != gameObject)
                {
                    Vector2 closestPoint = results.ClosestPoint(hand.transform.position);
                    Vector2 offset = (
                        closestPoint - (Vector2)hand.transform.position).normalized * 0.1f;
                    hand.transform.position = closestPoint - offset;
                    hand.connectedBody = body;
                    hand.enabled = true;
                    handVisual.UpdateSprite(true);

                    effect.Play();
                    AudioPlayer.Instance.PlaySound(_grabSound);
                }
            }
        }

        Rigidbody2D connectedA = _handL.connectedBody;
        Rigidbody2D connectedB = _handR.connectedBody;
        if (connectedA != null && connectedB != null &&
                connectedA != connectedB)
        {
            if (connectedA.TryGetComponent(out Cable a) &&
                    connectedB.TryGetComponent(out Cable b))
            {
                CableConnected?.Invoke(a, b);
            }
        }
    }

    private void OnDrawGizmosSelected()
    {
        Gizmos.DrawWireSphere(_handL.transform.position, 1f);
        Gizmos.DrawWireSphere(_handR.transform.position, 1f);
    }
}
